<?php
use adminmatrix\migration\Migrator;
use  adminmatrix\migration\db\Column;
use Phinx\Db\Adapter\AdapterInterface;

class AdminOrganize extends Migrator
{

    protected array  $menuItems = [
        ['id' => 17, 'path' => 'organize',  'name' => '组织构架', 'parent_id' => 0,   'component' => null, 'type' => 1, 'perms' => '','app' => 'adminapi', 'icon' => 'ant-icon-ApartmentOutlined', 'hidden' => 0],
        ['id' => 18, 'path' => 'OrganizationList', 'name' => '组织列表', 'parent_id' => 17, 'component' => 'system/organize/OrganizationList/index','app' => 'adminapi', 'type' => 2, 'perms' => '/adminapi/organize.organization/lists', 'icon' => 'ant-icon-ApartmentOutlined', 'hidden' => 0],
        ['id' => 19, 'path' => '',          'name' => '新增',     'parent_id' => 18,  'component' => null, 'type' => 3, 'perms' => '/adminapi/organize.organization/save','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 20, 'path' => '',          'name' => '更新',     'parent_id' => 18,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.organization/update','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 21, 'path' => '',          'name' => '删除',     'parent_id' => 18,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.organization/delete','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 22, 'path' => 'department', 'name' => '部门列表', 'parent_id' => 17,  'component' => 'system/organize/department/index', 'type' => 2, 'perms' => '/adminapi/organize.department/lists','app' => 'adminapi', 'icon' => 'ant-icon-AppstoreOutlined', 'hidden' => 0],
        ['id' => 23, 'path' => '',          'name' => '新增',     'parent_id' => 22,  'component' => null, 'type' => 3, 'perms' => '/adminapi/organize.department/save','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 24, 'path' => '',          'name' => '编辑',     'parent_id' => 22,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.department/update','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 25, 'path' => '',          'name' => '删除',     'parent_id' => 22,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.department/delete','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 26, 'path' => 'position',  'name' => '职务',     'parent_id' => 17,  'component' => 'system/organize/position/index', 'type' => 2, 'perms' => '/adminapi/organize.position/lists','app' => 'adminapi', 'icon' => 'ant-icon-AppstoreAddOutlined', 'hidden' => 0],
        ['id' => 27, 'path' => '',          'name' => '新增',     'parent_id' => 26,  'component' => null, 'type' => 3, 'perms' => '/adminapi/organize.position/save','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 28, 'path' => '',          'name' => '编辑',     'parent_id' => 26,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.position/update','app' => 'adminapi', 'icon' => '', 'hidden' => 0],
        ['id' => 29, 'path' => '',          'name' => '删除',     'parent_id' => 26,  'component' => '', 'type' => 3, 'perms' => '/adminapi/organize.position/delete','app' => 'adminapi', 'icon' => '', 'hidden' => 0]
    ];

    /**
    * Change Method.
    *
    * Write your reversible migrations using this method.
    *
    * More information on writing migrations is available here:
    * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
    *
    * The following commands can be used in this method and Phinx will
    * automatically reverse them when rolling back:
    *
    *    createTable
    *    renameTable
    *    addColumn
    *    renameColumn
    *    addIndex
    *    addForeignKey
    *
    * Remember to call "create()" or "update()" and NOT "save()" when working
    * with the Table class.
    */
   public function up()
   {
       // 记录开始时间
        $startTime = microtime(true);

        $this->output->info("==执行创建组织构架表");
        $this->createAdminOrganizationList();
//
       $this->output->info("==执行创建 组织部门表");
       $this->createAdminDepartment();


       $this->output->info("==执行创建 组织部门职位表");
       $this->createAdminPosition();

//       $this->output->info("== 执行创建 管理员关联组织、部门、职位表");
//       $this->createAdminOrganizeDepartmentPositionRelevance();

       $this->output->info("== 执行创建菜单插入");
       $this->saveMenu();

       // 记录结束时间
       $endTime = microtime(true);

       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');

       $this->output->info("== 创建组织结构完成 总计用时：{$executionTime}秒");
   }

   public function down(){

       $piex = env("DB_PREFIX");
       // 记录开始时间
       $startTime = microtime(true);

       $this->output->writeln("== 执行删除 管理员关联组织部门职位表");
       $this->table('admin_organize_department_position_relevance')->drop()->save();

       $this->output->writeln("== 执行删除 组织构架表");
       $this->table('admin_organization')->drop()->save();

       $this->output->writeln("== 执行删除 组织部门表");
       $this->table('admin_department')->drop()->save();

       $this->output->writeln("== 执行删除 组织部门职位表");
       $this->table('admin_position')->drop()->save();

       if($this->hasTable('admin_permission') ){
           $ids = [];
           foreach ($this->menuItems as $item) {
               if (isset($item['id'])) {
                   $ids[] = $item['id'];
               }
           }
           $placeholders = implode(',', $ids);
           # 删除菜单
           $this->execute("
                DELETE FROM {$piex}admin_permission WHERE id IN ($placeholders)
           ");
       }

       // 记录结束时间
       $endTime = microtime(true);

       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');

       $this->output->info("== 删除组织结构完成 总计用时：{$executionTime}秒");

   }

   private function saveMenu(){


       if ($this->hasTable('admin_permission') && $this->isMigratingUp())
       {
           $this->table('admin_permission')->insert($this->menuItems)->save();
           $this->output->info("== 创建菜单完成用");
       }

   }

   private function createAdminOrganizeDepartmentPositionRelevance()
   {
       if($this->hasTable('admin_organize_department_position_relevance'))
       {
           return $this->output->error("== 组织部门职位表已存在 === 跳过");

       }

       // 记录开始时间
       $startTime = microtime(true);
       $table = $this->table('admin_organize_department_position_relevance',[
           'engine' => 'InnoDB',
           'collation' => 'utf8mb4_general_ci',
           'id'=>false,
//           'primary_key'    =>  ['admin_id', 'organization_id', 'department_id'],
           'comment' => '管理员关联组织部门职位表',
       ]);

       $table
           ->addColumn('admin_id', 'integer', [
               'signed' => false,
               'comment' => '管理员ID'
           ])
           ->addColumn('organization_id', 'integer', [
               'null' => true,
               'signed' => false,
               'comment' => '组织ID'
           ])
           ->addColumn('department_id', 'integer', [
               'null' => true,
               'signed' => false,
               'comment' => '部门ID'
           ])
           ->addColumn('is_leader', 'integer', [
               'limit' => \Phinx\Db\Adapter\MysqlAdapter::INT_TINY,
               'default' => 0,
               'comment' => '是否为主管：1-是；0-否'
           ])
           ->addIndex(['admin_id'])
           ->addIndex(['organization_id'])
           ->addIndex(['department_id'])
           // 设置外键约束
           ->addForeignKey(
               'admin_id',
               'admin',
               'id',
               [
                   'delete' => 'CASCADE',
                   'update' => 'CASCADE',
                   'constraint' => 'fk_admin_org_admin'
               ]
           )
           ->addForeignKey(
               'organization_id',
               'admin_organization',
               'id',
               [
                   'delete' => 'CASCADE',
                   'update' => 'CASCADE',
                   'constraint' => 'fk_admin_org_organization'
               ]
           )
           ->addForeignKey(
               'department_id',
               'admin_department',
               'id',
               [
                   'delete' => 'CASCADE',
                   'update' => 'CASCADE',
                   'constraint' => 'fk_admin_org_department'
               ]
           )
           ->create();

       // 记录结束时间
       $endTime = microtime(true);
       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');
       $this->output->warning("== 创建 管理员关联组织部门职位表 完成 用时：{$executionTime}秒");

   }
    /**
     * 创建组织部门职位表
     * @return void
     */
   private function createAdminPosition()
   {
       if($this->hasTable('admin_position'))
       {
           return $this->output->error("== 组织部门职位表已存在 === 跳过");
       }

       // 记录开始时间
       $startTime = microtime(true);
       $this->output->writeln("== 执行创建组织部门职位表");

       $table = $this->table('admin_position' , [
           'engine' => 'InnoDB',
           'collation' => 'utf8mb4_general_ci',
           'comment' => '组织部门职位表',
           'id' => 'id',
           'primary_key' => ['id']
       ]);


       $table->addColumn('title' , 'string' , [
           'null'   =>  false,
           'limit'  =>  128,
           'comment'    =>  '组织名称'
       ])
           ->addColumn('parent_id' , 'integer' , [
               'null'   =>  true,
               'limit'  =>  11,
               'default'    =>  0,
               'comment'    =>  '父级组织'
           ])

           ->addColumn('department_id', 'integer', [
               'signed' => false,
               'comment' => '所属部门ID'
           ])

           ->addColumn('description' , 'text',[
               'null' => true,
               'comment' => '职位描述'
           ])
           ->addColumn('status' , AdapterInterface::PHINX_TYPE_TINY_INTEGER,[
               'limit'  =>  1,
               'default'    =>  1,
               'comment'    =>  '是否启用 0:不启用| 1:启用'
           ])
           ->addColumn('creator_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'comment'    =>  '创建者id'
           ])
           ->addColumn('leader_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'signed' => false,
               'comment'    =>  '负责人id'
           ])
           ->addColumn('create_time', 'integer', [
               'null' => true,
               'comment' => '创建时间'
           ])
           ->addColumn('update_time', 'integer', [
               'null' => true,
               'comment' => '更新时间'
           ])
           ->addColumn('delete_time', 'integer', [
               'null' => true,
               'comment' => '删除时间（软删除）'
           ]);

//       $table  ->addIndex(['department_id'])
//           ->addIndex(['creator_id'])
//           // 设置职位表外键约束
//           ->addForeignKey(
//               'department_id',
//               'admin_department',
//               'id',
//               [
//                   'delete' => 'CASCADE',  // 部门删除时级联删除职位
//                   'update' => 'CASCADE',
//                   'constraint' => 'fk_position_department'
//               ]
//           );

       $table->create();

       // 记录结束时间
       $endTime = microtime(true);
       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');
       $this->output->warning("== 创建 创建组织部门职位表 完成 用时：{$executionTime}秒");
   }
    /**
     * 创建组织部门表
     * @return void
     */
   private function createAdminDepartment()
   {
       if($this->hasTable('admin_department'))
       {
           return $this->output->error("== 组织部门表已存在 === 跳过");
       }

       // 记录开始时间
       $startTime = microtime(true);
       $this->output->writeln("== 执行创建组织部门表");

       $table = $this->table('admin_department' , [
           'engine' => 'InnoDB',
           'collation' => 'utf8mb4_general_ci',
           'comment' => '组织部门表',
           'id' => 'id',
           'primary_key' => ['id']
       ]);



       $table->addColumn('title' , 'string' , [
           'null'   =>  false,
           'limit'  =>  128,
           'comment'    =>  '组织名称'
       ])
           ->addColumn('parent_id' , 'integer' , [
               'null'   =>  true,
               'limit'  =>  11,
               'default'    =>  0,
               'comment'    =>  '父级组织'
           ])

           ->addColumn('organization_id', 'integer', [
               'signed' => false,
               'comment' => '所属组织ID'
           ])

           ->addColumn('description' , 'text',[
               'null' => true,
               'comment' => '部门描述'
           ])
           ->addColumn('status' , AdapterInterface::PHINX_TYPE_TINY_INTEGER,[
               'limit'  =>  1,
               'default'    =>  1,
               'comment'    =>  '是否启用 0:不启用| 1:启用'
           ])
           ->addColumn('creator_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'comment'    =>  '创建者id'
           ])
           ->addColumn('leader_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'signed' => false,
               'comment'    =>  '负责人id'
           ])
           ->addColumn('create_time', 'integer', [
               'null' => true,
               'comment' => '创建时间'
           ])
           ->addColumn('update_time', 'integer', [
               'null' => true,
               'comment' => '更新时间'
           ])
           ->addColumn('delete_time', 'integer', [
               'null' => true,
               'comment' => '删除时间（软删除）'
           ]);

       $table ->addIndex(['organization_id'])
           ->addIndex(['parent_id'])
           ->addIndex(['creator_id'])
           ->addIndex(['leader_id']);

//       $table // 设置部门表外键约束
//            ->addForeignKey(
//                'organization_id',
//                'admin_organization',
//                'id',
//                [
//                    'delete' => 'CASCADE',  // 组织删除时级联删除部门
//                    'update' => 'CASCADE',
//                    'constraint' => 'fk_department_organization'
//                ]
//            )
//            ->addForeignKey(
//                'parent_id',
//                'department',
//                'id',
//                [
//                    'delete' => 'SET_NULL',  // 父部门删除时子部门保留
//                    'update' => 'CASCADE',
//                    'constraint' => 'fk_department_parent'
//                ]
//            );

       $table->create();

       // 记录结束时间
       $endTime = microtime(true);
       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');
       $this->output->warning("== 创建 组织部门表 完成 用时：{$executionTime}秒");

   }

    /**
     * 创建组织管理列表
     * @return void
     */
   private function createAdminOrganizationList(){
       if($this->hasTable('admin_organization'))
       {
           return $this->output->error("== 组织构架表已存在 === 跳过");
       }
       // 记录开始时间
       $startTime = microtime(true);

       $this->output->info("=== 开始创建 组织构架表");

       $table = $this->table("admin_organization" , [
           'engine' => 'InnoDB',
           'collation' => 'utf8mb4_general_ci',
           'comment' => '组织构架表',
           'id' => 'id',
           'primary_key' => ['id']
       ]);

       $table->addColumn('title' , 'string' , [
           'null'   =>  false,
           'limit'  =>  128,
           'comment'    =>  '组织名称'
       ])
           ->addColumn('parent_id' , 'integer' , [
               'null'   =>  true,
               'limit'  =>  11,
               'default'    =>  0,
               'comment'    =>  '父级组织'
           ])

           ->addColumn('description' , 'text',[
               'null' => true,
               'comment' => '组织描述'
           ])
           ->addColumn('status' , AdapterInterface::PHINX_TYPE_TINY_INTEGER,[
               'limit'  =>  1,
               'default'    =>  1,
               'comment'    =>  '是否启用 0:不启用| 1:启用'
           ])
           ->addColumn('creator_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'comment'    =>  '创建者id'
           ])
           ->addColumn('leader_id' , 'integer' , [
               'null'   =>  false,
               'limit'  =>  11,
               'signed' => false,
               'comment'    =>  '负责人id'
           ])
           ->addColumn('create_time', 'integer', [
               'null' => true,
               'comment' => '创建时间'
           ])
           ->addColumn('update_time', 'integer', [
               'null' => true,
               'comment' => '更新时间'
           ])
           ->addColumn('delete_time', 'integer', [
               'null' => true,
               'comment' => '删除时间（软删除）'
           ]);

       # 创建索引
       $table->addIndex('parent_id' , [
           'name'   =>    'parent_id',
       ])->addIndex('creator_id' , [
           'name'   =>  'creator_id',
       ])->addIndex('leader_id' , [
           'name'   =>  'leader_id',
       ]);




       $table->create();

//       $this->table("admin_organization")
//           ->addForeignKey('parent_id' , 'admin_organization' , 'id',[
//           'delete' => 'SET_NULL',  // 父记录删除时设置子记录parent_id为NULL
//           'update' => 'CASCADE',   // 父记录ID更新时级联更新子记录
//           'constraint' => 'fk_organization_parent'
//       ])->update();
       // 记录结束时间
       $endTime = microtime(true);

       // 计算执行时间（秒）
       $executionTime = $endTime - $startTime;
       $executionTime = number_format($executionTime, 6, '.', '');

       $this->output->info("== 创建组织构架表完成用时：{$executionTime}秒");

   }
}